package spring.cloud.tasks.executor.executor.task.execute_runtime_context;

import lombok.extern.slf4j.Slf4j;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class TasksExecuteRuntimeContext {
    public static final ConcurrentHashMap<String, TaskExecuteRuntimeContext> taskIdToTaskExecuteRuntimeContextMap = new ConcurrentHashMap<String, TaskExecuteRuntimeContext>();

    public static final TaskExecuteRuntimeContext getTaskExecuteRuntimeContext(String taskId) {
        TasksExecuteRuntimeContext.taskIdToTaskExecuteRuntimeContextMap.put(taskId, new TaskExecuteRuntimeContext());
        TaskExecuteRuntimeContext taskExecuteRuntimeContext = taskIdToTaskExecuteRuntimeContextMap.get(taskId);
        return taskExecuteRuntimeContext;
    }

    /**
     * 一定会有值得，一般任务不会超过1024.后期会增加一个定时任务对过期的实例进行清理
     */
    public interface Business {
        void doBusiness(ConcurrentHashMap<String, TaskItemExecuteRuntimeContext> taskItemIndexToTaskItemExecuteRuntimeContextMap, TaskItemExecuteRuntimeContext taskItemExecuteRuntimeContext);
    }

    /**
     * 这种遍历不会主动的创建实例，只有当实例存在的时候才进行处理
     */
    public static void ergodicTaskExecuteRuntimeContextAndHandleBusiness(String taskId, Business business) {
        TaskExecuteRuntimeContext taskExecuteRuntimeContext = TasksExecuteRuntimeContext.taskIdToTaskExecuteRuntimeContextMap.get(taskId);
        if (taskExecuteRuntimeContext == null) {
            return;
        }
        ConcurrentHashMap<String, TaskInstanceExecuteRuntimeContext> taskInstanceIdToTaskInstanceExecuteRuntimeContextMap = taskExecuteRuntimeContext.taskInstanceIdToTaskInstanceExecuteRuntimeContextMap;
        if (taskInstanceIdToTaskInstanceExecuteRuntimeContextMap == null) {
            return;
        }
        Set<String> taskInstanceIdSet = taskInstanceIdToTaskInstanceExecuteRuntimeContextMap.keySet();
        for (String taskInstanceId : taskInstanceIdSet) {//for循环中必须有continue
            TaskInstanceExecuteRuntimeContext taskInstanceExecuteRuntimeContext = taskInstanceIdToTaskInstanceExecuteRuntimeContextMap.get(taskInstanceId);
            if (taskInstanceExecuteRuntimeContext == null) {
                continue;
            }
            ConcurrentHashMap<String, TaskStageExecuteRuntimeContext> taskStageToTaskStageExecuteRuntimeContextMap = taskInstanceExecuteRuntimeContext.taskStageToTaskStageExecuteRuntimeContextMap;
            if (taskStageToTaskStageExecuteRuntimeContextMap == null) {
                return;
            }
            ConcurrentHashMap.KeySetView<String, TaskStageExecuteRuntimeContext> taskStageSet = taskStageToTaskStageExecuteRuntimeContextMap.keySet();
            for (String taskStage : taskStageSet) {
                TaskStageExecuteRuntimeContext taskStageExecuteRuntimeContext = taskStageToTaskStageExecuteRuntimeContextMap.get(taskStage);
                if (taskExecuteRuntimeContext == null) {
                    continue;
                }
                //
                ConcurrentHashMap<String, TaskStage$typeExecuteRuntimeContext> taskStage$typeToTaskStage$typeExecuteRuntimeContextMap = taskStageExecuteRuntimeContext.taskStage$typeToTaskStage$typeExecuteRuntimeContextMap;
                if (taskStage$typeToTaskStage$typeExecuteRuntimeContextMap == null) {
                    continue;
                }
                Set<String> taskStage$typeSet = taskStage$typeToTaskStage$typeExecuteRuntimeContextMap.keySet();
                for (String taskStage$type : taskStage$typeSet) {
                    TaskStage$typeExecuteRuntimeContext taskStage$typeExecuteRuntimeContext = taskStage$typeToTaskStage$typeExecuteRuntimeContextMap.get(taskStage$type);
                    if (taskStage$typeExecuteRuntimeContext == null) {
                        continue;
                    }
                    ConcurrentHashMap<String, TaskItemExecuteRuntimeContext> taskItemIndexToTaskItemExecuteRuntimeContextMap = taskStage$typeExecuteRuntimeContext.taskItemIndexToTaskItemExecuteRuntimeContextMap;
                    if (taskItemIndexToTaskItemExecuteRuntimeContextMap == null) {
                        continue;
                    }
                    Set<String> taskItemIndexSet = taskItemIndexToTaskItemExecuteRuntimeContextMap.keySet();
                    for (String taskItemIndex : taskItemIndexSet) {
                        TaskItemExecuteRuntimeContext taskItemExecuteRuntimeContext = taskItemIndexToTaskItemExecuteRuntimeContextMap.get(taskItemIndex);
                        if (taskItemExecuteRuntimeContext == null) {
                            continue;
                        }
                        try {
                            business.doBusiness(taskItemIndexToTaskItemExecuteRuntimeContextMap, taskItemExecuteRuntimeContext);
                        } catch (Throwable e) {
                            log.error(e.getMessage(), e);
                        }

                    }
                }
            }

        }
    }
}
